﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcControlToolkit
{
    /// <summary>
    /// The ModalPopup extender allows a page to display content to the user in a 
    /// "modal" manner which prevents the user from interacting with the rest of 
    /// the page. The modal content can be any hierarchy of controls and is displayed 
    /// above a background that can have a custom style applied to it. 
    /// 
    /// When displayed, only the modal content can be interacted with; clicking on 
    /// the rest of the page does nothing. When the user is done interacting with 
    /// the modal content, a click of an OK/Cancel control dismisses the modal 
    /// content and optionally runs custom script. 
    /// 
    /// The custom script will typically be used to apply whatever changes were made
    /// while the modal mode was active. You can also absolutely position a modal 
    /// popup by setting the X and Y properties. By default it is centered on the 
    /// page, however if just X or Y is specified then it is centered vertically or 
    /// horizontally. 
    /// </summary>
    public static class ModalPopupExtensions
    {
        private static readonly ModalPopupRepositionMode DEFAULT_POSITION = ModalPopupRepositionMode.RepositionOnWindowResizeAndScroll;

        /// <summary>
        /// Creates a ModalPopup extender 
        /// </summary>
        /// <param name="elementId">The ID of the element that activates the modal popup</param>
        /// <param name="popupControlId">The ID of the element to display as a modal popup </param>        
        public static string ModalPopup(this AjaxHelper helper, string elementId, string popupControlId)
        {
            return helper.ModalPopup(elementId, popupControlId, "");
        }

        /// <summary>
        /// Creates a ModalPopup extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that activates the modal popup</param>
        /// <param name="popupControlId">The ID of the element to display as a modal popup </param>
        /// <param name="backgroundCssClass">The CSS class to apply to the background when the modal popup is displayed</param>
        public static string ModalPopup(this AjaxHelper helper, string elementId, string popupControlId, string backgroundCssClass)
        {
            return helper.ModalPopup(elementId, popupControlId, backgroundCssClass, true);
        }

        /// <summary>
        /// Creates a ModalPopup extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that activates the modal popup</param>
        /// <param name="popupControlId">The ID of the element to display as a modal popup </param>
        /// <param name="backgroundCssClass">The CSS class to apply to the background when the modal popup is displayed</param>
        /// <param name="dropShadow">True to automatically add a drop-shadow to the modal popup. Default is False</param>        
        public static string ModalPopup(this AjaxHelper helper, string elementId, string popupControlId, string backgroundCssClass, bool dropShadow)
        {
            return helper.ModalPopup(elementId, popupControlId, backgroundCssClass, dropShadow, "", "");
        }

        /// <summary>
        /// Creates a ModalPopup extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that activates the modal popup</param>
        /// <param name="popupControlId">The ID of the element to display as a modal popup </param>
        /// <param name="backgroundCssClass">The CSS class to apply to the background when the modal popup is displayed</param>
        /// <param name="dropShadow">True to automatically add a drop-shadow to the modal popup. Default is False</param>
        /// <param name="okControlId">The ID of the element that dismisses the modal popup</param>
        /// <param name="cancelControlId">The ID of the element that cancels the modal popup</param>
        public static string ModalPopup(this AjaxHelper helper, string elementId, string popupControlId, string backgroundCssClass, bool dropShadow, string okControlId, string cancelControlId)
        {
            return helper.ModalPopup(elementId, popupControlId, backgroundCssClass, dropShadow, okControlId, cancelControlId, "", "");
        }

        /// <summary>
        /// Creates a ModalPopup extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that activates the modal popup</param>
        /// <param name="popupControlId">The ID of the element to display as a modal popup </param>
        /// <param name="backgroundCssClass">The CSS class to apply to the background when the modal popup is displayed</param>
        /// <param name="dropShadow">True to automatically add a drop-shadow to the modal popup. Default is False</param>
        /// <param name="okControlId">The ID of the element that dismisses the modal popup</param>
        /// <param name="cancelControlId">The ID of the element that cancels the modal popup</param>
        /// <param name="okScript">Script to run when the modal popup is dismissed with the OkControlID</param>
        /// <param name="cancelScript">Script to run when the modal popup is dismissed with the CancelControlID</param>
        /// <param name="popupDragHandleControlId">The ID of the embedded element that contains the popup header/title which will be used as a drag handle</param>
        public static string ModalPopup(this AjaxHelper helper, string elementId, string popupControlId, string backgroundCssClass, bool dropShadow, string okControlId, string cancelControlId, string okScript, string cancelScript)
        {
            return helper.ModalPopup(elementId, popupControlId, backgroundCssClass, dropShadow, okControlId, cancelControlId, okScript, cancelScript, "");
        }

        /// <summary>
        /// Creates a ModalPopup extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that activates the modal popup</param>
        /// <param name="popupControlId">The ID of the element to display as a modal popup </param>
        /// <param name="backgroundCssClass">The CSS class to apply to the background when the modal popup is displayed</param>
        /// <param name="dropShadow">True to automatically add a drop-shadow to the modal popup. Default is False</param>
        /// <param name="okControlId">The ID of the element that dismisses the modal popup</param>
        /// <param name="cancelControlId">The ID of the element that cancels the modal popup</param>
        /// <param name="okScript">Script to run when the modal popup is dismissed with the OkControlID</param>
        /// <param name="cancelScript">Script to run when the modal popup is dismissed with the CancelControlID</param>
        /// <param name="popupDragHandleControlId">The ID of the embedded element that contains the popup header/title which will be used as a drag handle</param>
        public static string ModalPopup(this AjaxHelper helper, string elementId, string popupControlId, string backgroundCssClass, bool dropShadow, string okControlId, string cancelControlId, string okScript, string cancelScript, string popupDragHandleControlId)
        {
            return helper.ModalPopup(elementId, popupControlId, backgroundCssClass, dropShadow, okControlId, cancelControlId, okScript, cancelScript, popupDragHandleControlId, 0, 0, ModalPopupRepositionMode.None);
        }

        /// <summary>
        /// Creates a ModalPopup extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that activates the modal popup</param>
        /// <param name="popupControlId">The ID of the element to display as a modal popup </param>
        /// <param name="backgroundCssClass">The CSS class to apply to the background when the modal popup is displayed</param>
        /// <param name="dropShadow">True to automatically add a drop-shadow to the modal popup. Default is False</param>
        /// <param name="okControlId">The ID of the element that dismisses the modal popup</param>
        /// <param name="cancelControlId">The ID of the element that cancels the modal popup</param>
        /// <param name="okScript">Script to run when the modal popup is dismissed with the OkControlID</param>
        /// <param name="cancelScript">Script to run when the modal popup is dismissed with the CancelControlID</param>
        /// <param name="popupDragHandleControlId">The ID of the embedded element that contains the popup header/title which will be used as a drag handle</param>
        /// <param name="x">The X coordinate of the top/left corner of the modal popup (the popup will be centered horizontally if not specified)</param>
        /// <param name="y">The Y coordinate of the top/left corner of the modal popup (the popup will be centered vertically if not specified)</param>
        /// <param name="repositionMode">The setting that determines if the popup needs to be repositioned when the window is resized or scrolled</param>
        public static string ModalPopup(this AjaxHelper helper, string elementId, string popupControlId, string backgroundCssClass, bool dropShadow, string okControlId, string cancelControlId, string okScript, string cancelScript, string popupDragHandleControlId, int x, int y, ModalPopupRepositionMode repositionMode)
        {
            RouteValueDictionary props = new RouteValueDictionary();
            props.Add("PopupControlID", popupControlId);
            props.AddIfNotDefault("BackgroundCssClass", backgroundCssClass);
            props.AddIfNotEqual("DropShadow", dropShadow, false);
            
            props.AddIfNotDefault("OkControlID", okControlId);
            props.AddIfNotDefault("OnOkScript", okScript);
            props.AddIfNotDefault("CancelControlID", cancelControlId);
            props.AddIfNotDefault("OnCancelScript", cancelScript);
            props.AddIfNotDefault("PopupDragHandleControlID", popupDragHandleControlId);

            if (x >= 0)
                props.Add("X", x);

            if (y >= 0)
                props.Add("Y", y);

            props.AddIfNotEqual("RepositionMode", repositionMode, DEFAULT_POSITION);

            return helper.ModalPopup(elementId, props);
        }

        /// <summary>
        /// Creates a ModalPopup extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that activates the modal popup</param>
        /// <param name="properties">An object containing the properties to be set</param>
        public static string ModalPopup(this AjaxHelper helper, string elementId, object properties)
        {
            var sb = new StringBuilder();

            // Add Microsoft Ajax library   
            sb.Append(helper.MicrosoftAjaxInclude());
                        
            // Add toolkit scripts   
            sb.Append(helper.ToolkitInclude(
                    "AjaxControlToolkit.ExtenderBase.BaseScripts.js",
                    "AjaxControlToolkit.Common.Common.js",
                    "AjaxControlToolkit.DynamicPopulate.DynamicPopulateBehavior.js",
                    "AjaxControlToolkit.RoundedCorners.RoundedCornersBehavior.js",                    
                    "AjaxControlToolkit.Compat.Timer.Timer.js",
                    "AjaxControlToolkit.DropShadow.DropShadowBehavior.js",
                    "AjaxControlToolkit.Compat.DragDrop.DragDropScripts.js",
                    "AjaxControlToolkit.DragPanel.FloatingBehavior.js",
                    "AjaxControlToolkit.ModalPopup.ModalPopupBehavior.js"
                ));

            // Perform $create               
            sb.AppendLine(helper.Create("AjaxControlToolkit.ModalPopupBehavior", properties, elementId));

            return sb.ToString();
        }
    }

    #region [Enumerations]

    public enum ModalPopupRepositionMode
    {
        None = 0,
        RepositionOnWindowResize = 1,
        RepositionOnWindowScroll = 2,
        RepositionOnWindowResizeAndScroll = 3
    }

    #endregion
}
